package com.twp.auth.service.manage;

import com.twp.auth.domain.authority.Menu;
import com.twp.auth.repository.auth.MenuRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.Predicate;
import java.util.*;

@Slf4j
@Service
@Transactional
public class MenuService {
    @Autowired
    MenuRepository menuRepository;

    @PersistenceContext
    EntityManager entityManager;

    public Page<Menu> find(Menu menu, Pageable pageable, boolean needsChildren){
        Page<Menu> menus = menuRepository.findAll(
                (root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> predicates = new ArrayList<>();
                    if(!StringUtils.isEmpty(menu.getId())){
                        predicates.add(criteriaBuilder.equal(root.get("id"),menu.getId()));
                    }
                    if(!StringUtils.isEmpty(menu.getCode())){
                        predicates.add(criteriaBuilder.equal(root.get("code"), menu.getCode()));
                    }
                    if(!StringUtils.isEmpty(menu.getTitle())){
                        predicates.add(criteriaBuilder.equal(root.get("title"), menu.getTitle()));
                    }
                    return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
                }
                ,pageable
        );
        if (menus.hasContent()){
            menus.getContent().stream().forEach(
                    m->m.setChildren(needsChildren?m.getChildrenRef():null)
            );
        }

        return menus;
    }

    public List<Menu> find(Menu menu){
        Sort sort = new Sort(new Sort.Order("menuOrder"));
        List<Menu> menus = menuRepository.findAll(
                (root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> predicates = new ArrayList<>();

                    if(menu.getId()!=null){
                        predicates.add(criteriaBuilder.equal(root.get("id"), menu.getId()));
                    }

                    if(!StringUtils.isEmpty(menu.getCode())){
                        predicates.add(criteriaBuilder.equal(root.get("code"), menu.getCode()));
                    }
                    if(!StringUtils.isEmpty(menu.getTitle())){
                        predicates.add(criteriaBuilder.equal(root.get("title"), menu.getTitle()));
                    }
                    if(menu.getLevel()!=null){
                        predicates.add(criteriaBuilder.equal(root.get("level"), menu.getLevel()));
                    }
                    return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
                },sort
        );
        return menus;
    }

    public void deleteById(Integer id){
        menuRepository.delete(id);
    }
    public Integer saveOrUpdate(Menu menu){
        menu.setUpdateTime(new Date());
        Optional.ofNullable(
                menu.getParentId()
        ).ifPresent(
                parentId->{
                    Menu menuP = menuRepository.findOne(parentId);
                    menuP.getChildrenRef().add(menu);
                }
        );
        Menu menu_ = menuRepository.save(menu);
        return menu_.getId();
    }

    public List<Menu> loadTreeData(Integer roleId){
        // 获取根菜单下的树
        Menu menu = menuRepository.findAllByParentId(null);
        // 根据roleId获取已关联的
        menu.setCurrentRoleId(roleId);
//        while (!menu.getChildren().isEmpty()){
//
//        }
        return new ArrayList(){{add(menu);}};
    }
}
